﻿using System;
using System.Reflection;
using System.Collections.Generic;

using rlTodayMakeSkin.GUI;
using rlTodayMakeSkin.Project.Attributes;
using rlTodayMakeSkin.Project.XmlElement;
using rlTodayMakeSkin.Project.XmlElement.XmlSubElements;

namespace rlTodayMakeSkin.Project.XmlElement.Properties
{
    /// <summary>
    /// Contains a list of XmlElementProperty getted by a
    /// XmlElement object
    /// </summary>
    public class XmlElementPropertiesList
    {
        private SkinControl sc;
        private XmlElementProperty[] arrProps;

        public XmlElementPropertiesList(SkinControl sc)
        {
            this.sc = sc;
            initPropList();
        }

        XmlElementPropertiesList() { sc = null; }

        /********************************
         PUBLIC MEMBERS
         ********************************/

        /// <summary>
        /// Returns an array that contains properties of
        /// a XmlElement
        /// </summary>
        /// <returns>An array of XmlElementProperty</returns>
        public XmlElementProperty[] GetPropertiesList()
        {
            XmlElementProperty[] props = new XmlElementProperty[arrProps.Length];
            arrProps.CopyTo(props, 0);
            return props;/**/
            //return arrProps;
        }

        /// <summary>
        /// Change value of specificated property
        /// </summary>
        /// <param name="pName">the name of the property whose change value</param>
        /// <param name="val">new value for this property</param>
        /// <remarks>val must be of the same type of the type of this property but
        /// any control be done</remarks>
        public void ChangePropertyValue(string pName, Object val)
        {
            for (int i = 0; i < arrProps.Length - 1; i++)
            {
                if (arrProps[i].Name.Equals(pName))
                {
                    arrProps[i].Value = val;
                    break;
                }
            }

        }

        /// <summary>
        /// Returns SkinControl object associated
        /// </summary>
        public SkinControl GetSkinControl()
        {
            return sc;
        }

        /// <summary>
        /// Gets a new XmlElementProperty initialized with this
        /// PropertyInfo and its associated instance
        /// </summary>
        /// <param name="pi"></param>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static XmlElementProperty GetElementProperty(PropertyInfo pi, object instance)
        {
            PropertyDescriptionAttribute pda = null;
            pda = (PropertyDescriptionAttribute)Attribute.GetCustomAttribute(pi, typeof(PropertyDescriptionAttribute));
            //only properties that must compare in property window have marked with PropertyDescription attribute
            if (pda != null)
                return new XmlElementProperty(pi.Name, pi.GetValue(instance, null), pda.PropertyType, pda.Description, pda.Version, pda.ReadOnlyProperty);
            else
                return null;
        }

        /******************************
         FRIENDS MEMBERS
         ******************************/


        /********************************
         PRIVATE MEMBERS
         ********************************/
        /// <summary>
        /// Initializes the list of the property, reading properties of associated XmlElement
        /// </summary>
        private void initPropList()
        {
            PropertyInfo[] pies = sc.SkinElement.GetType().GetProperties();
            List<XmlElementProperty> piList = new List<XmlElementProperty>();
            
            foreach (PropertyInfo pi in pies)
            {
                XmlElementProperty p = GetElementProperty(pi, sc.SkinElement);
                if (p != null) piList.Add(p);                
            }
            arrProps = piList.ToArray();
        }

    }//end class
}
